package redis

import (
	"errors"
	"math"
	"strconv"
	"time"
	"web_app/models"

	"github.com/go-redis/redis"
)

const (
	oneWeek      = 7 * 24 * 3600 //一周的秒数
	scorePerVote = 432           //每次投票加的分数
)

var (
	Err = errors.New("超出投票时间")
)

// CreatePost 创建帖子投票时间以及默认分数
func CreatePost(post *models.Post) (err error) {
	pipeline := rdb.TxPipeline()
	pipeline.ZAdd(getRedisKey(KeyPostTimeZSet), redis.Z{
		Score:  float64(time.Now().Unix()),
		Member: post.ID,
	})
	pipeline.ZAdd(getRedisKey(KeyPostScoreZSet), redis.Z{
		Score:  float64(time.Now().Unix()),
		Member: post.ID,
	})
	pipeline.SAdd(getRedisKey(KeyCommunityPF+strconv.Itoa(int(post.CommunityId))), post.ID)
	_, err = pipeline.Exec()
	return
}

// VoteForPost 给帖子进行投票方法
func VoteForPost(voteData *models.ParamsVoteData) error {

	//判断投票限制、去redis里面取帖子发布时间
	postTime := rdb.ZScore(getRedisKey(KeyPostTimeZSet), strconv.Itoa(int(voteData.PostID))).Val()
	//判断是否超出投票时间
	if float64(time.Now().Unix())-postTime > oneWeek {
		return Err
	}
	//查找当前用户对帖子的投票记录
	ov := rdb.ZScore(getRedisKey(keyPostVotedZSetPF)+strconv.Itoa(int(voteData.PostID)), strconv.Itoa(int(voteData.UserID))).Val()
	var op float64
	if float64(voteData.Direction) > ov {
		op = 1
	} else {
		op = -1
	}
	//计算两次投票插值的绝对值
	diff := math.Abs(float64(voteData.Direction) - ov)
	pipeline := rdb.TxPipeline()
	pipeline.ZIncrBy(getRedisKey(KeyPostScoreZSet), op*diff*scorePerVote, strconv.Itoa(int(voteData.PostID)))
	//更新用户投票信息
	if voteData.Direction == 0 {
		pipeline.ZRem(getRedisKey(keyPostVotedZSetPF)+strconv.Itoa(int(voteData.PostID)), strconv.Itoa(int(voteData.UserID)))
	} else {
		pipeline.ZAdd(getRedisKey(keyPostVotedZSetPF)+strconv.Itoa(int(voteData.PostID)), redis.Z{
			Score:  float64(voteData.Direction),
			Member: voteData.UserID,
		})
	}
	_, err := pipeline.Exec()
	return err
}
